Skip to content

build(abi/ffi): wire the Idris2 ABI + Zig FFI to compile (first time)#79

Merged
hyperpolymath merged 2 commits into
mainfrom
wire-abi-ffi-build
Jul 7, 2026
Merged

build(abi/ffi): wire the Idris2 ABI + Zig FFI to compile (first time)#79
hyperpolymath merged 2 commits into
mainfrom
wire-abi-ffi-build

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

What

The ABI (src/abi/, Idris2) and FFI (ffi/zig/) layers had never actually
built
— no ipkg, module names that didn't resolve, broken proofs, missing FFI
glue types, and a Zig build.zig on a pre-0.15 API. This wires both green
and adds just recipes to keep them that way.

Idris2 ABI — idris2 --build rpa-elysium-abi.ipkg ✅ (5/5 modules)

  • New rpa-elysium-abi.ipkg (sourcedir=src/abi; mirrors HAR's har-abi.ipkg).
  • Flatten module names to the src/abi/ layout — this also fixes
    Foreign.idr's ABI-vs-Abi case mismatch (it imported modules that
    didn't exist).
  • Proof fixes in Types.idr/Layout.idr: eventKindTagValid /
    eventKindTagFitsInByte every clause wrongly used LTE 5 5; each now matches
    its actual tag (0→LTEZero, 1→LTESucc LTEZero, …).
  • Layout.idr: import Data.Nat (LTE/GT were undefined).
  • Foreign.idr: define the FFI glue that was referenced but never declared
    Handle (+ createHandle/handlePtr) and Result (Ok=0..NullPointer=4,
    matching the Zig enum); fix registerCallback to take a raw C-callable pointer
    (an Idris closure can't be cast to AnyPtr).

Zig FFI — zig build + zig build test

  • Port build.zig to the Zig 0.15 API (addSharedLibrary/addStaticLibrary
    addLibrary + shared module + linkage; link_libc for the C allocator).
  • Fix main.zig for 0.15 (opaque-with-fields → struct; callconv(.C)
    callconv(.c)).
  • Produces librpa_ffi.{a,so}; tests pass. The 11 exported C symbols match
    Foreign.idr's %foreign declarations, and the Result codes agree.

Justfile

verify-abi, build-ffi, test-ffi, verify-abi-ffi.

Known follow-ups (not compile issues)

  • Foreign.idr's process wrapper treats result 0 as error while
    processArray and the Zig side treat 0 as ok — the success convention
    needs reconciling (correctness, with a test).
  • generated/abi/ C headers still unimplemented (the formal Idris↔Zig bridge).
  • LinearDispatch.eph (Ephapax) needs its own toolchain to build.

Follows the shared-ABI adoption (#78).

🤖 Generated with Claude Code

hyperpolymath and others added 2 commits July 7, 2026 11:40
The ABI (src/abi/, Idris2) and FFI (ffi/zig/) layers had never actually built.
This wires both green and adds `just` recipes to keep them that way.

Idris2 ABI — new `rpa-elysium-abi.ipkg` (sourcedir=src/abi; mirrors HAR's
har-abi.ipkg). Fixes so all five modules typecheck:
- flatten module names to the src/abi/ layout (RpaElysium.Abi.* -> bare), which
  also fixes Foreign.idr's ABI-vs-Abi case mismatch (it imported modules that
  did not exist);
- Types.idr/Layout.idr: correct the `eventKindTagValid` / `eventKindTagFitsInByte`
  LTE proofs — every clause wrongly used `LTE 5 5`; each now matches its tag
  (0->LTEZero, 1->LTESucc LTEZero, ...);
- Layout.idr: `import Data.Nat` (LTE/GT were undefined);
- Foreign.idr: define the FFI glue types that were referenced but never declared
  — `Handle` (+ createHandle/handlePtr), `Result` (Ok=0..NullPointer=4, matching
  the Zig enum); fix `registerCallback` to take a raw C-callable pointer (an
  Idris closure cannot be `cast` to AnyPtr).

Zig FFI — port build.zig to the Zig 0.15 API (addSharedLibrary/addStaticLibrary
-> addLibrary + shared module + linkage; link_libc for the C allocator) and fix
main.zig for 0.15 (opaque-with-fields -> struct; callconv(.C) -> callconv(.c)).
`zig build` now produces librpa_ffi.{a,so} and `zig build test` passes. The 11
exported C symbols match Foreign.idr's %foreign declarations, and the Result
codes agree.

Justfile: `verify-abi`, `build-ffi`, `test-ffi`, `verify-abi-ffi`.

Known follow-ups (not compile issues): Foreign.idr's `process` wrapper treats
result 0 as error while `processArray`/the Zig side treat 0 as ok — the success
convention needs reconciling; generated/abi/ C headers still unimplemented;
LinearDispatch.eph (Ephapax) needs its own toolchain to build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- grant secret-scanner reusable its requested job permissions
- drop invalid timeout-minutes on reusable-call jobs
- drop hashFiles() from job-level if: expressions
@hyperpolymath
hyperpolymath merged commit 76ad499 into main Jul 7, 2026
21 of 25 checks passed
@hyperpolymath
hyperpolymath deleted the wire-abi-ffi-build branch July 7, 2026 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant